from approval_service.approval.mappers.approval_mapper import ApprovalMapper
from approval_service.approval.mappers.reimbursement_approval_fi_mapper import ReimbursementApprovalFiMapper
from approval_service.approval.service.client.reimbursement_client import ReimbursementClient
from approval_service.approval.service.client.travel_client import TravelClient
from approval_service.approval.service.client.user_client import UserClient
from commons.entity.enum.reimbursement_approval_enum import ReimbursementApprovalEnum
from commons.entity.po.approval import Approval
from commons.entity.po.reimbursement_approval_fi import ReimbursementApprovalFi
from commons.entity.query.approval_query import ApprovalQuery
from commons.entity.query.reimbursement_approval_fi_query import ReimbursementApprovalFiQuery
from commons.entity.vo.pagination_result_vo import PaginationResultVO
from commons.entity.vo.reimbursement_vo import ReimbursementVO
from commons.utils.copy_tools import CopyTools


class ReimbursementApprovalFiService:
    def __init__(self):
        self.reimbursement_approval_fi_mapper = ReimbursementApprovalFiMapper()
        self.travel_client = TravelClient()
        self.user_client = UserClient()
        self.reimbursement_client = ReimbursementClient()
        self.approval_mapper = ApprovalMapper()

    def find_list_by_param(self, reimbursement_approval_fi_query=None):
        """
        业务逻辑：根据多个参数查询财务人员审批报销申请记录列表。
        :param reimbursement_approval_fi_query: ReimbursementApprovalFiQuery 实例，包含查询过滤条件。
        :return: 包含财务人员审批报销申请记录信息字典的列表。
        """
        print("ReimbursementApprovalFiService find_list_by_param")
        print(reimbursement_approval_fi_query)

        return self.reimbursement_approval_fi_mapper.select_list(ReimbursementApprovalFi,
                                                                 reimbursement_approval_fi_query)

    def find_count_by_param(self, reimbursement_approval_fi_query=None):
        """
        业务逻辑：根据多个参数统计财务人员审批报销申请记录数量。
        :param reimbursement_approval_fi_query: ReimbursementApprovalFiQuery 实例，包含查询过滤条件。
        :return: 符合条件的财务人员审批报销申请记录数量。
        """
        print("ReimbursementApprovalFiService find_count_by_param")
        print(reimbursement_approval_fi_query)

        return self.reimbursement_approval_fi_mapper.select_count(ReimbursementApprovalFi,
                                                                  reimbursement_approval_fi_query)

    def get_reimbursement_approval_fi_by_reimbursement_approval_fi_id(self, reimbursement_approval_fi_id):
        """
        业务逻辑：获取单条财务人员审批报销申请记录。
        :param reimbursement_approval_fi_id: str
        :return: 财务人员审批报销申请记录字典或 None
        """
        print("ReimbursementApprovalFiService get_reimbursement_approval_fi_by_reimbursement_approval_fi_id ")
        print(reimbursement_approval_fi_id)

        return self.reimbursement_approval_fi_mapper.select_by_reimbursement_approval_fi_id(
            reimbursement_approval_fi_id)

    def add(self, reimbursement_approval_fi_bean):
        """
        业务逻辑：添加一个新的财务人员审批报销申请记录。
        :param reimbursement_approval_fi_bean: ReimbursementApprovalFi 类实例，包含审批记录信息。
        :return: 插入操作是否成功（True/False）。
        """
        print("ReimbursementApprovalFiService add reimbursement_approval_fi")
        print(reimbursement_approval_fi_bean)

        return self.reimbursement_approval_fi_mapper.insert(reimbursement_approval_fi_bean)

    def add_batch(self, reimbursement_approval_fi_list_bean):
        """
        业务逻辑：批量添加财务人员审批报销申请记录。
        :param reimbursement_approval_fi_list_bean: 包含多个 ReimbursementApprovalFi 类实例的列表，包含需要插入的审批记录信息。
        :return: 插入操作成功的审批记录数量。
        """
        print("ReimbursementApprovalFiService add_batch reimbursement_approval_fi")
        print(reimbursement_approval_fi_list_bean)

        if not reimbursement_approval_fi_list_bean:
            print(
                "No reimbursement approval records to add. The input list is either null or empty.")
            return 0

        return self.reimbursement_approval_fi_mapper.insert_batch(reimbursement_approval_fi_list_bean)

    def add_or_update_batch(self, reimbursement_approval_fi_list_bean):
        """
        业务逻辑：批量插入或更新财务人员审批报销申请记录信息。
        :param reimbursement_approval_fi_list_bean: 包含多个 ReimbursementApprovalFi 类实例的列表，包含需要插入或更新的审批记录信息。
        :return: 插入或更新成功的审批记录数量。
        """
        print(
            "ReimbursementApprovalFiService add_or_update_batch reimbursement_approval_fi")
        print(reimbursement_approval_fi_list_bean)

        if not reimbursement_approval_fi_list_bean:
            print(
                "No reimbursement approval records to add or update. The input list is either null or empty.")
            return 0

        return self.reimbursement_approval_fi_mapper.insert_or_update_batch(ReimbursementApprovalFi,
                                                                            reimbursement_approval_fi_list_bean)

    def update_by_param(self, reimbursement_approval_fi_bean, reimbursement_approval_fi_query):
        """
        业务逻辑：根据多个条件更新财务人员审批报销申请记录信息。
        :param reimbursement_approval_fi_bean: ReimbursementApprovalFi 类实例或字典，包含需要更新的字段及其新值。
        :param reimbursement_approval_fi_query: ReimbursementApprovalFiQuery 类实例或字典，包含用于定位记录的过滤条件。
        :return: 更新成功的数量。
        """
        print("ReimbursementApprovalFiService update_by_param")
        print(reimbursement_approval_fi_bean)
        print(reimbursement_approval_fi_query)

        return self.reimbursement_approval_fi_mapper.update_by_params(ReimbursementApprovalFi,
                                                                      reimbursement_approval_fi_bean,
                                                                      reimbursement_approval_fi_query)

    def delete_by_param(self, reimbursement_approval_fi_query):
        """
        业务逻辑：根据多个条件删除财务人员审批报销申请记录信息。
        :param reimbursement_approval_fi_query: ReimbursementApprovalFiQuery 类实例或字典，包含用于定位记录的过滤条件。
        :return: 删除成功的数量。
        """
        print("ReimbursementApprovalFiService delete_by_param")
        print(reimbursement_approval_fi_query)

        return self.reimbursement_approval_fi_mapper.delete_by_param(ReimbursementApprovalFi,
                                                                     reimbursement_approval_fi_query)

    def update_reimbursement_approval_fi_by_reimbursement_approval_fi_id(self, reimbursement_approval_fi_bean,
                                                                         reimbursement_approval_fi_id):
        """
        业务逻辑：根据 reimbursement_approval_fi_id 更新财务人员审批报销申请记录信息。
        :param reimbursement_approval_fi_id: str
        :param reimbursement_approval_fi_bean: ReimbursementApprovalFi 类实例，包含需要更新的财务审批报销记录属性。
        :return: 更新成功信息或错误信息。
        """
        print("ReimbursementApprovalFiService update_reimbursement_approval_fi_by_reimbursement_approval_fi_id ")
        print(
            f"reimbursement_approval_fi_id: {reimbursement_approval_fi_id}, reimbursement_approval_fi_bean: {reimbursement_approval_fi_bean}")

        return self.reimbursement_approval_fi_mapper.update_by_reimbursement_approval_fi_id(
            reimbursement_approval_fi_bean, reimbursement_approval_fi_id)

    def delete_reimbursement_approval_fi_by_reimbursement_approval_fi_id(self, reimbursement_approval_fi_id):
        """
        业务逻辑：根据 reimbursement_approval_fi_id 删除财务人员审批报销记录。
        :param reimbursement_approval_fi_id: str
        :return: 删除成功或错误。
        """
        print("ReimbursementApprovalFiService delete_reimbursement_approval_fi_by_reimbursement_approval_fi_id ")
        print(reimbursement_approval_fi_id)

        return self.reimbursement_approval_fi_mapper.delete_by_reimbursement_approval_fi_id(
            reimbursement_approval_fi_id)

    def get_approve_reimbursement_record_fi(self, user_id, page_no, page_size):
        """
        业务逻辑：获取审批的报销记录列表，包含分页信息。
        :param user_id: 财务人员ID
        :param page_no: 当前页码
        :param page_size: 每页显示数量
        :return: PaginationResultVO 对象，包含分页结果和审批的报销记录
        """
        print("ReimbursementApprovalFiService get_approve_reimbursement_record_fi")
        print(
            f"user_id: {user_id}, page_no: {page_no}, page_size: {page_size}")

        # 查询所有已审批的报销申请记录
        reimbursement_approval_fi_query = ReimbursementApprovalFiQuery(
            finance_id=user_id)
        reimbursement_approval_fi_list = self.find_list_by_param(
            reimbursement_approval_fi_query)

        if not reimbursement_approval_fi_list:
            return None

        # 创建报销ID映射
        reimbursement_approval_fi_map = {reimbursement_approval_fi.reimbursement_id: reimbursement_approval_fi
                                         for reimbursement_approval_fi in reimbursement_approval_fi_list}

        # 获取报销申请信息
        reimbursement_id_list = list(set([reimbursement_approval_fi.reimbursement_id
                                          for reimbursement_approval_fi in reimbursement_approval_fi_list]))
        reimbursement_list = self.reimbursement_client.get_reimbursements_by_id_list(
            reimbursement_id_list)

        # 获取出差信息
        travel_id_list = list(
            set([reimbursement.travel_id for reimbursement in reimbursement_list]))
        travel_list = self.travel_client.get_all_travels_by_id_list(
            travel_id_list)
        travel_map = {travel.travel_id: travel for travel in travel_list}

        # 获取用户信息
        user_id_list = list(set([travel.user_id for travel in travel_list]))
        user_list = self.user_client.get_all_users_by_id_list(user_id_list)
        user_map = {user.user_id: user for user in user_list}

        reimbursement_vo_list = []

        for reimbursement in reimbursement_list:
            reimbursement_vo = CopyTools.copy(reimbursement, ReimbursementVO)

            reimbursement_vo.reimbursement = (
                reimbursement.food_cost + reimbursement.hotel_cost + reimbursement.transport_cost)

            reimbursement_approval_fi = reimbursement_approval_fi_map.get(
                reimbursement.reimbursement_id)
            reimbursement_vo.payment = reimbursement_approval_fi.payment if reimbursement_approval_fi else 0

            travel = travel_map.get(reimbursement.travel_id)
            reimbursement_vo.travel_reason = travel.travel_reason
            reimbursement_vo.travel_detail = travel.travel_detail
            reimbursement_vo.start_date = travel.start_date
            reimbursement_vo.end_date = travel.end_date

            user = user_map.get(travel.user_id) if travel else None
            reimbursement_vo.user_id = user.user_id
            reimbursement_vo.user_name = user.name
            reimbursement_vo.user_phone = user.phone
            reimbursement_vo.user_email = user.email
            reimbursement_vo.position = user.position

            approval_query = ApprovalQuery(travel_id=reimbursement.travel_id)
            approval_list = self.approval_mapper.select_list(
                Approval, approval_query)
            approval = approval_list[0]
            reimbursement_vo.approval_id = approval.approval_id
            reimbursement_vo.reimbursement_status = approval.reimbursement_approval_fi
            reimbursement_vo.reimbursement_status_name = ReimbursementApprovalEnum.get_by_type(
                approval.reimbursement_approval_fi).msg
            reimbursement_vo.reimbursement_rejection = approval.reimbursement_rejection_fi

            reimbursement_vo_list.append(reimbursement_vo)

        count = len(reimbursement_vo_list)

        # start = (page_no - 1) * page_size
        # end = min(start + page_size, count)

        # total_page = count // page_size if count % page_size == 0 else (
        #     count // page_size) + 1

        return PaginationResultVO(
            count, page_size, page_no, 0, reimbursement_vo_list)

    def get_reimbursement_approval_fi_by_reimbursement_id(self, reimbursement_id):
        """
        业务逻辑：获取单条财务人员审批报销申请记录。
        :param reimbursement_id: str
        :return: 财务人员审批报销申请记录字典或 None
        """
        print("ReimbursementApprovalFiService get_reimbursement_approval_fi_by_reimbursement_id ")
        print(reimbursement_id)

        return self.reimbursement_approval_fi_mapper.select_by_reimbursement_id(
            reimbursement_id)